package liuliu.throughwaring.control.net;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import net.tsz.afinal.FinalDb;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import liuliu.custom.method.Utils;
import liuliu.custom.model.Cryptography;
import liuliu.throughwaring.model.CompanyModel;
import liuliu.throughwaring.model.InvokeReturn;
import liuliu.throughwaring.model.Key;
import liuliu.throughwaring.model.ModifiedModel;
import liuliu.throughwaring.model.PersonModel;
import liuliu.throughwaring.model.TerminalModel;

/**
 * Created by Administrator on 2015/11/13.
 */
public class HttpTask extends Thread {
    private TerminalModel mTerminal;//设备信息
    InvokeReturn mInvokeReturn;//返回结果
    private Context mContext;
    FinalDb finalDb;
    String methodString = "";
    String info = "";
    boolean isArray = false;
    TaskListener mTaskListener;
    String modelName;
    String url = "http://10.0.3.2:10309/Services/Social.aspx";

    public HttpTask(Context context) {
        this.mContext = context;
        finalDb = FinalDb.create(context);
        String ip = Utils.ReadString(Key.KEY_IP);
        String port = Utils.ReadString(Key.KEY_PORT);
        url = "http://" + ip + ":" + port + "/Services/Social.aspx";
    }

    public interface TaskListener {
        void onTaskResult(boolean result, InvokeReturn invokeReturn);
    }
    public void start(String method, String info, String model, TaskListener listener) {
        List<TerminalModel> list = finalDb.findAllByWhere(TerminalModel.class, "TerminalCode='" + Utils.getImei(mContext) + "'");
        if (list.size() > 0) {
            mTerminal = list.get(0);
        } else {
            mTerminal = new TerminalModel();
            try {
                mTerminal.setTerminalPassword(Cryptography.hashPassword("Password"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            mTerminal.setTerminalId("Guest");
        }
        this.modelName = model;
        this.methodString = method;
        this.mTaskListener = listener;
        this.info = info;
        this.isArray = isArray;
        if (!this.isAlive()) {
            start();
        }

    }

    public void start(String method, String info, String model, boolean isArray, TaskListener listener) {
        List<TerminalModel> list = finalDb.findAllByWhere(TerminalModel.class, "TerminalCode='" + Utils.getImei(mContext) + "'");
        if (list != null) {
            if (list.size() > 0) {
                mTerminal = list.get(0);
            } else {
                mTerminal = new TerminalModel();
                try {
                    mTerminal.setTerminalPassword(Cryptography.hashPassword("Password"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }
                mTerminal.setTerminalId("Guest");
            }
        }
        this.modelName = model;
        this.methodString = method;
        this.mTaskListener = listener;
        this.info = info;
        this.isArray = isArray;
        start();
    }

    @Override
    public void run() {
        Looper.prepare();
        try {
            String imei = "IMEI";
            if (!methodString.equals("GetTerminal")) {
                imei = Utils.getImei(mContext);
            }
            String psw = mTerminal.getTerminalPassword();
            String terminalId = mTerminal.getTerminalId();

            String ticket = Cryptography.AES_Encode(imei, terminalId, psw);
            if (methodString.equals("GetCode")) {
                getCode(terminalId, psw, imei, ticket);
            } else if (methodString.equals("GetPersons")) {
                getPersons(terminalId, ticket, psw);
            } else {
                HttpPost(terminalId, psw, imei, ticket);
            }
        } catch (Exception e) {
            handler.obtainMessage(1).sendToTarget();
        }
        Looper.loop();
        super.run();
    }

    /**
     * 得到企业人人员信息
     */
    public void getPersons(String terminalId, String ticket, String password) {
        try {
            finalDb.deleteAll(PersonModel.class);
            List<CompanyModel> list = new ArrayList<CompanyModel>();
            list = finalDb.findAll(CompanyModel.class);
            System.out.println("list;;;" + list.size());
            int i = 1;
            for (CompanyModel companyModel : list) {
                i++;
                String info = companyModel.getInfo();
                info = Cryptography.AES_Encode(info, terminalId, password);
                String entity = "Information=" + URLEncoder.encode(info);
                Map<String, String> params = new TreeMap<String, String>();
                params.put("Id", terminalId);
                params.put("TerminalId", terminalId);
                params.put("DataType", "Data");
                params.put("Password", password);
                params.put("TerminalCode", terminalId);
                params.put("Version", 1 + "");
                params.put("Ticket", ticket);
                params.put("Objective", "GetPersons");
                handler.obtainMessage(0, HttpUtility.httpPost(url, params, entity)).sendToTarget();
            }
        } catch (Exception e) {
            handler.obtainMessage(1).sendToTarget();
        }
    }

    /**
     * 更新字典
     */
    public void getCode(String terminalId, String psw, String imei, String ticket) throws Exception {
        String[] items = {};
        List<ModifiedModel> list = finalDb.findAll(ModifiedModel.class);
        if (list.size() > 0) {
            String item = list.get(0).getModifiedItem();
            items = item.split(",");
        } else {
            items = new String[]{"Code_CompanyType", "Code_PersonStatus", "Code_Area", "Code_CardType", "Code_Native", "Code_Nation", "Code_Sex","Code_TrafficType"};
        }
        Utils.WriteString("CodeName", items[items.length - 1]);
        for (String str : items) {
            info = "CodeName=" + str;
            String infomation = Cryptography.AES_Encode(info, terminalId, psw);
            String entity = "Information=" + URLEncoder.encode(infomation);
            Map<String, String> params = new TreeMap<String, String>();
            params.put("Id", terminalId);
            params.put("DataType", "Data");
            params.put("Password", psw);
            params.put("TerminalCode", imei);//IMEI
            params.put("Version", "1");
            params.put("Ticket", ticket);
            params.put("Objective", methodString);
            Message msg = handler.obtainMessage(0);
            Bundle data = new Bundle();
            data.putString("CodeName", str);
            msg.setData(data);
            msg.obj = HttpUtility.httpPost(url, params, entity);
            msg.sendToTarget();
        }
        //handler.obtainMessage(0).sendToTarget();
    }

    /**
     * 设置参数，向后台发出请求
     */
    private void HttpPost(String terminalId, String psw, String imei, String ticket) throws Exception {
        String entity = "";

        if (!info.equals("")) {
            String infomation = Cryptography.AES_Encode(info, terminalId, psw);
            entity = "Information=" + URLEncoder.encode(infomation);
        }
        Map<String, String> params = new TreeMap<String, String>();
        params.put("Id", terminalId);
        params.put("DataType", "Data");
        params.put("Password", psw);
        params.put("TerminalCode", imei);//IMEI
        params.put("Version", "1");
        params.put("Ticket", ticket);
        params.put("Objective", methodString);
        handler.obtainMessage(0, HttpUtility.httpPost(url, params, entity)).sendToTarget();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (mTaskListener != null) {
                if (!methodString.equals("")) {
                    if (msg.what != 0) {
                        mTaskListener.onTaskResult(false, null);
                    } else {
                        HTTPResponse resp = (HTTPResponse) msg.obj;
                        if (null != resp) {
                            if (!parse(resp.content)) {
                                mTaskListener.onTaskResult(false, mInvokeReturn);
                            } else {
                                if (methodString.equals("GetCode")) {
                                    Bundle data = msg.getData();
                                    String CodeName = data.getString("CodeName");
                                    System.out.println("Codename" + CodeName);
                                    mInvokeReturn.setMessage(CodeName);
                                }
                            mTaskListener.onTaskResult(true, mInvokeReturn);
                        }
                    } else {
                            mInvokeReturn = new InvokeReturn();
                            mInvokeReturn.setSuccess(false);
                            mInvokeReturn.setMessage("null");
                            mTaskListener.onTaskResult(true, mInvokeReturn);
                        }
                    }
                } else {
                    mInvokeReturn = new InvokeReturn();
                    mInvokeReturn.setSuccess(false);
                    mInvokeReturn.setMessage("请填写要访问的方法名称");
                    mTaskListener.onTaskResult(true, mInvokeReturn);
                }
            } else {
                stop();
            }
        }
    };

    //解析数据json
    public boolean parse(String json) {
        System.out.println("json:::"+json);
        if (null != json) {
            try {
                mInvokeReturn = new InvokeReturn();
                mInvokeReturn.setSuccess(true);
                Field[] fields = new Field[0];//返回模型字段
                Object objectModel = null;//返回模型
                JSONObject jsonObject = new JSONObject(json);
                List<Object> objectList = new ArrayList<Object>();
                if (!Utils.getJsonString(jsonObject, "Success").equals("true")) {
                    mInvokeReturn.setSuccess(false);
                    String mes = jsonObject.getString("Message");
                    mInvokeReturn.setMessage(mes);
                    return false;
                }
                String state = jsonObject.getString("State");
                if (methodString.equals("GetView")) {
                    mInvokeReturn.setMessage(state);
                } else if (!(state.equals("null") || state.equals("false") || state.equals("true"))) {
                    //是否为集合
                    if (isArray) {
                        JSONArray array = jsonObject.getJSONArray("State");
                        for (int i = 0; i < array.length(); i++) {
                            JSONObject object = array.getJSONObject(i);
                            objectModel = getObject(object);
                            objectList.add(objectModel);
                        }
                    } else {
                        if (methodString.equals("GetImage")) {
                            mInvokeReturn.setMessage(jsonObject.getString("State"));
                        } else if (methodString.equals("AddCompany")) {
                            String string = jsonObject.getString("State");
                            mInvokeReturn.setMessage(string);
                        } else if (methodString.equals("GetNationAlarm") && jsonObject.toString().contains("State")) {
                            JSONArray array = jsonObject.getJSONArray("State");
                            for (int i = 0; i < array.length(); i++) {
                                objectModel = array.getString(i);
                                objectList.add(objectModel);
                            }
                        } else {
                            //解析model
                            JSONObject stateobject = jsonObject.getJSONObject("State");
                            if (state != null) {
                                objectModel = getObject(stateobject);
                                objectList.add(objectModel);
                            }
                        }
                    }
                }
                mInvokeReturn.setData(objectList);
            } catch (JSONException e) {
                mInvokeReturn.setSuccess(false);
                e.printStackTrace();
                return false;
            } catch (Exception e) {
                mInvokeReturn.setSuccess(false);
                e.printStackTrace();
                return false;
            }
            return true;
        } else {
            return false;
        }
    }

    private Object getObject(JSONObject jsonObject) throws Exception {
        Field[] fields;
        Object objectModel = new Object();
        if (jsonObject != null) {
            if (!modelName.equals("")) {
                objectModel = Utils.getBean(modelName);
                fields = objectModel.getClass().getDeclaredFields();
                for (Field field : fields) {

                    String filedtype = field.getType().getSimpleName();
                    if (filedtype.equals("int")) {

                        if (!Utils.getJsonString(jsonObject, field.getName()).equals("")) {
                            Utils.setPropertyInt(objectModel, field.getName(), Utils.getJsonString(jsonObject, field.getName()));
                        }
                    } else {
                        if (!Utils.getJsonString(jsonObject, field.getName()).equals("")) {
                            Utils.setProperty(objectModel, field.getName(), Utils.getJsonString(jsonObject, field.getName()));
                        }
                    }
                }
            }
        }
        return objectModel;
    }
}
